﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

using mKoenig.PictureSlide.Properties;

namespace mKoenig.PictureSlide
{
  public class Render
  {
    #region declaratins
    public static string[] RenderName = { "expand from left to right", "fly from left to right", "fly from right to left", "fly from top to bottom",
                                          "fly from bottom to top", "expand from top to bottom", "expand from bottom to top", "expand from right to left",
                                          "expand from inside", "expand from middle to left/right", "expand from middle to up/bottom", "fly in from top left",
                                          "fly in from bottom left", "fly in from top right", "fly in from bottom right", "reduce from outside",
                                          "move left/right up/down", "move up/down left/right", "open left/right up/down 4 stripes", "alpha blending" ,
                                          "black&white blending", "sephia blending", "next picture", "6 blocks",
                                          "open from top left", "open from bottom left", "open from top right", "open from bottom right",
                                          "open from left","open from right","open from top","open from bottom",
                                          "open from midle","12 blocks","Photo frame","24 blocks",
                                          "Method 37","Method 38","Method 39","Method 40"};
    public static int Count = 36;

    private Size size;
    private ImageData img;

    private Image front;
    private Graphics gFront;
    private Image back;
    private Graphics gBack;

    private float frameCounter = 0.0f;

    public static float slideShowTransistionFrames = 100;

    private List<Rectangle> points36;

    private Settings setting = Settings.Default;
    private DateTime startTime1 = DateTime.Now;
    private DateTime startTime2 = DateTime.Now.AddMinutes(20);
    private DateTime startTime3 = DateTime.Now.AddMinutes(40);

    private bool doOnce;

    public class ImageData
    {
      public Image Image;
      public string Name = string.Empty;
      public string Date = string.Empty;
      public string Info = string.Empty;
    }

    #endregion

    public Render(Size TargetSize)
    {
      size = TargetSize;
      slideShowTransistionFrames = setting.TransitionTime / 20;

      front = new Bitmap(this.size.Width, this.size.Height);
      gFront = Graphics.FromImage(front);

      back = new Bitmap(this.size.Width, this.size.Height);
      gBack = Graphics.FromImage(back);
    }
    public void DoRender(float Frame, int Mode, Graphics TargetGraphics, ImageData Slice, bool Preview)
    {
      img = Slice;
      frameCounter = Frame;

      if (frameCounter < (slideShowTransistionFrames + 20))
      {
        #region doTransition
        doOnce = false;

        try
        {
          TargetGraphics.DrawImageUnscaled(back, new Point(0, 0));

          callRender(Mode);
          back = (Image)front.Clone();
        }
        catch { }
        #endregion
      }
      else
      {
        if (!doOnce)
        {
          // make sure we have done full render
          try
          {
            TargetGraphics.DrawImageUnscaled(back, new Point(0, 0));

            callRender(Mode);
            back = (Image)front.Clone();
          }
          catch { }

          // now draw one more
          doOnce = true;
          TargetGraphics.DrawImageUnscaled(back, new Point(0, 0));

          if (!Preview)
          {
            string txt = string.Empty;

            #region upper part
            if (setting.ShowFileName)
            {
              if (setting.PictureMode == "random")
              {
                txt = "File: " + Path.GetFileName(img.Name) + " (random)";
                drawStringWithBackground(txt, TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, 10.0f));
              }
              else
              {
                txt = "File: " + Path.GetFileName(img.Name) + " (sequence)";
                drawStringWithBackground(txt, TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, 10.0f));
              }
            }

            //if (Main.Paused == true)
            if (false)
            {
              txt = "Screensaver paused, press <SPACE>";
              SizeF aSize = TargetGraphics.MeasureString(txt, new Font("Arial", 20.0f));
              drawStringWithBackground(txt, TargetGraphics, Color.White, Color.Red, new Font("Arial", 20.0f), new PointF(size.Width - 10.0f - aSize.Width, 10.0f));
            }

            if (setting.ShowFileDate)
            {
              txt = "Date: " + img.Date;
              drawStringWithBackground(txt, TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, 45.0f));
            }
            #endregion

            #region debug mode
            string strMode = string.Empty;
            if (setting.ShowDebug)
            {
              drawStringWithBackground("Render method " + (Mode + 1).ToString() + " / " + RenderName[Mode], TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, 80.0f));

              if (setting.PanStretch) strMode += "Pan ";
              if (setting.PanStretch && setting.BlurBackground) strMode += "/ ";
              if (setting.BlurBackground) strMode += "Blur ";

              drawStringWithBackground(strMode, TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, 115.0f));
              drawStringWithBackground("File no. " + img.Info, TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, 150.0f));
              drawStringWithBackground("Frame: " + ((int)frameCounter).ToString(), TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, 185.0f));
            }
            #endregion

            #region lower part
            if ((startTime1.Minute == DateTime.Now.Minute) ||
                (startTime2.Minute == DateTime.Now.Minute) ||
                (startTime3.Minute == DateTime.Now.Minute))
            {
              txt = "MkSlide Screensaver by Mark König 2012";
              SizeF aSize = TargetGraphics.MeasureString(txt, new Font("Arial", 20.0f));
              drawStringWithBackground(txt, TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(size.Width - 10.0f - aSize.Width, size.Height - 45.0f));
            }
            if (setting.ShowActualTime)
            {
              txt = "Time: " + DateTime.Now.ToShortTimeString();
              drawStringWithBackground(txt, TargetGraphics, setting.TextFrontColor, setting.TextBackColor, new Font("Arial", 20.0f), new PointF(10.0f, size.Height - 45.0f));
            }
            #endregion
          }
        }
      }
    }

    private void callRender(int Mode)
    {
      switch (Mode)
      {
        case 0:
          RenderMethod1(gFront);
          break;
        case 1:
          RenderMethod2(gFront);
          break;
        case 2:
          RenderMethod3(gFront);
          break;
        case 3:
          RenderMethod4(gFront);
          break;
        case 4:
          RenderMethod5(gFront);
          break;
        case 5:
          RenderMethod6(gFront);
          break;
        case 6:
          RenderMethod7(gFront);
          break;
        case 7:
          RenderMethod8(gFront);
          break;
        case 8:
          RenderMethod9(gFront);
          break;
        case 9:
          RenderMethod10(gFront);
          break;
        case 10:
          RenderMethod11(gFront);
          break;
        case 11:
          RenderMethod12(gFront);
          break;
        case 12:
          RenderMethod13(gFront);
          break;
        case 13:
          RenderMethod14(gFront);
          break;
        case 14:
          RenderMethod15(gFront);
          break;
        case 15:
          RenderMethod16(gFront);
          break;
        case 16:
          RenderMethod17(gFront);
          break;
        case 17:
          RenderMethod18(gFront);
          break;
        case 18:
          RenderMethod19(gFront);
          break;
        case 19:
          RenderMethod20(gFront);
          break;
        case 20:
          RenderMethod21(gFront);
          break;
        case 21:
          RenderMethod22(gFront);
          break;
        case 22:
          RenderMethod23(gFront);
          break;
        case 23:
          RenderMethod24(gFront);
          break;
        case 24:
          RenderMethod25(gFront);
          break;
        case 25:
          RenderMethod26(gFront);
          break;
        case 26:
          RenderMethod27(gFront);
          break;
        case 27:
          RenderMethod28(gFront);
          break;
        case 28:
          RenderMethod29(gFront);
          break;
        case 29:
          RenderMethod30(gFront);
          break;
        case 30:
          RenderMethod31(gFront);
          break;
        case 31:
          RenderMethod32(gFront);
          break;
        case 32:
          RenderMethod33(gFront);
          break;
        case 33:
          RenderMethod34(gFront);
          break;
        case 34:
          RenderMethod35(gFront);
          break;
        case 35:
          RenderMethod36(gFront);
          break;
      }
    }
    private void drawStringWithBackground(string Text, Graphics TargetGraphics, Color Pen, Color BackColor, Font DrawFont, PointF Point)
    {
      SolidBrush drawBrush = new SolidBrush(Pen);
      SizeF aSize = TargetGraphics.MeasureString(Text, DrawFont);

      Rectangle rect = new Rectangle((int)Point.X, (int)Point.Y, (int)aSize.Width, (int)aSize.Height);
      TargetGraphics.FillRectangle(new SolidBrush(Color.FromArgb(setting.TextAlpha, BackColor.R, BackColor.G, BackColor.B)), rect);

      TargetGraphics.DrawString(Text,
                                DrawFont,
                                drawBrush,
                                Point);
    }

    #region render methods

    // expand from left to right
    private Graphics RenderMethod1(Graphics e)
    {
      float iStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float iExpandWidth = frameCounter * iStep;
      if (iExpandWidth >= size.Width)
      {
        iExpandWidth = size.Width;
      }

      e.DrawImage(img.Image, new Rectangle(0, 0, (int)iExpandWidth, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly from left to right
    private Graphics RenderMethod2(Graphics e)
    {
      float iStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float iPosX = frameCounter * iStep - (float)size.Width;
      if (iPosX >= 0)
      {
        iPosX = 0;
      }

      e.DrawImage(img.Image, new Rectangle((int)iPosX, 0, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly from right to left
    private Graphics RenderMethod3(Graphics e)
    {
      float iStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }
      float posx = (float)size.Width - (frameCounter * iStep);
      if (posx <= 0)
      {
        posx = 0;
      }

      e.DrawImage(img.Image, new Rectangle((int)posx, 0, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly from top to bottom
    private Graphics RenderMethod4(Graphics e)
    {
      float iStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }
      float posy = frameCounter * iStep - (float)size.Height;
      if (posy >= 0)
      {
        posy = 0;
      }

      e.DrawImage(img.Image, new Rectangle(0, (int)posy, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly from bottom to top
    private Graphics RenderMethod5(Graphics e)
    {
      float iStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }
      float posy = (float)size.Height - (frameCounter * iStep);
      if (posy < 0)
      {
        posy = 0;
      }
      e.DrawImage(img.Image, new Rectangle(0, (int)posy, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);

      return e;
    }
    // expand from top to bottom
    private Graphics RenderMethod6(Graphics e)
    {
      float iStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float newheight = frameCounter * iStep;
      if (newheight >= size.Height)
      {
        newheight = size.Height;
      }

      e.DrawImage(img.Image, new Rectangle(0, 0, size.Width, (int)newheight), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);

      return e;
    }
    // expnd from bottom to top
    private Graphics RenderMethod7(Graphics e)
    {
      float iStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float newheight = frameCounter * iStep;
      if (newheight >= size.Height)
      {
        newheight = size.Height;
      }

      e.DrawImage(img.Image, new Rectangle(0, size.Height - (int)newheight, size.Width, (int)newheight), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);

      return e;
    }
    // expand from right to left
    private Graphics RenderMethod8(Graphics e)
    {
      float iStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float iExpandWidth = frameCounter * iStep;
      if (iExpandWidth >= size.Width)
      {
        iExpandWidth = size.Width;
      }

      float posx = size.Width - iExpandWidth;
      if (posx < 0) posx = 0;

      e.DrawImage(img.Image, new Rectangle((int)posx, 0, Convert.ToInt32(iExpandWidth), size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // expand from inside
    private Graphics RenderMethod9(Graphics e)
    {
      float iStepX = (float)size.Width / slideShowTransistionFrames;
      float iStepY = (float)size.Height / slideShowTransistionFrames;

      if (0 == iStepX)
      {
        iStepX = 1;
      }

      if (0 == iStepY)
      {
        iStepY = 1;
      }

      float newheight = frameCounter * iStepY;
      float newwidth = frameCounter * iStepX;

      if (newheight >= size.Height)
      {
        newheight = (float)size.Height;
      }

      if (newwidth >= size.Width)
      {
        newwidth = (float)size.Width;
      }

      float posx = ((float)size.Width - newwidth) / 2;
      float posy = ((float)size.Height - newheight) / 2;

      e.DrawImage(img.Image, new Rectangle((int)posx, (int)posy, (int)newwidth, (int)newheight), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);

      return e;
    }
    // expand from middle to left/right
    private Graphics RenderMethod10(Graphics e)
    {
      float iStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float iExpandWidth = (frameCounter * iStep);
      if (iExpandWidth >= size.Width)
      {
        iExpandWidth = size.Width;
      }
      float posX = (size.Width / 2) - (iExpandWidth / 2);

      e.DrawImage(img.Image, new Rectangle((int)posX, 0, Convert.ToInt32(iExpandWidth), size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // expand from middle to up/bottom
    private Graphics RenderMethod11(Graphics e)
    {
      float iStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float newheight = frameCounter * iStep;
      if (newheight >= size.Height)
      {
        newheight = size.Height;
      }
      float posY = (size.Height / 2) - (newheight / 2);


      e.DrawImage(img.Image, new Rectangle(0, (int)posY, size.Width, (int)newheight), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly in from top left
    private Graphics RenderMethod12(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iPosX = frameCounter * xStep - (float)size.Width;
      if (iPosX >= 0)
      {
        iPosX = 0;
      }
      float iPosY = frameCounter * yStep - (float)size.Height;
      if (iPosY >= 0)
      {
        iPosY = 0;
      }

      e.DrawImage(img.Image, new Rectangle((int)iPosX, (int)iPosY, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly in from bottom left
    private Graphics RenderMethod13(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iPosX = frameCounter * xStep - (float)size.Width;
      if (iPosX >= 0)
      {
        iPosX = 0;
      }
      float iPosY = (float)size.Height - ((float)frameCounter * yStep);
      if (iPosY < 0)
      {
        iPosY = 0;
      }

      e.DrawImage(img.Image, new Rectangle((int)iPosX, (int)iPosY, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly in from top right
    private Graphics RenderMethod14(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iPosX = (float)size.Width - (frameCounter * xStep);
      if (iPosX < 0)
      {
        iPosX = 0;
      }
      float iPosY = frameCounter * yStep - (float)size.Height;
      if (iPosY >= 0)
      {
        iPosY = 0;
      }

      e.DrawImage(img.Image, new Rectangle((int)iPosX, (int)iPosY, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // fly in from bottom right
    private Graphics RenderMethod15(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iPosX = (float)size.Width - (frameCounter * xStep);
      if (iPosX < 0)
      {
        iPosX = 0;
      }
      float iPosY = (float)size.Height - (frameCounter * yStep);
      if (iPosY < 0)
      {
        iPosY = 0;
      }

      e.DrawImage(img.Image, new Rectangle((int)iPosX, (int)iPosY, size.Width, size.Height), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }
    // reduce from outside
    private Graphics RenderMethod16(Graphics e)
    {
      float iStepX = ((float)size.Width * 1.0f) / slideShowTransistionFrames;
      float iStepY = ((float)size.Height * 1.0f) / slideShowTransistionFrames;

      if (0 == iStepX)
      {
        iStepX = 1;
      }

      if (0 == iStepY)
      {
        iStepY = 1;
      }

      float newheight = ((float)size.Height * 2.0f) - (frameCounter * iStepY);
      float newwidth = ((float)size.Width * 2.0f) - (frameCounter * iStepX);

      if (newheight <= size.Height)
      {
        newheight = size.Height;
      }

      if (newwidth <= size.Width)
      {
        newwidth = size.Width;
      }

      //center align the texture
      float posx = ((size.Width - newwidth) / 2);
      float posy = ((size.Height - newheight) / 2);

      e.DrawImage(img.Image, new Rectangle((int)posx, (int)posy, (int)newwidth, (int)newheight), 0, 0, img.Image.Width, img.Image.Height, GraphicsUnit.Pixel);
      return e;
    }

    // move left/right up/down
    private Graphics RenderMethod17(Graphics e)
    {
      float iStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float newheightT = frameCounter * iStep;
      if (newheightT >= size.Height)
      {
        newheightT = size.Height;
      }

      Rectangle rectS1 = new Rectangle(0, 0, img.Image.Width / 2, img.Image.Height);
      Rectangle rectS2 = new Rectangle(img.Image.Width / 2, 0, img.Image.Width / 2, img.Image.Height);

      Rectangle rectT1 = new Rectangle(0, (int)newheightT - size.Height, size.Width / 2, size.Height);
      Rectangle rectT2 = new Rectangle(size.Width / 2, size.Height - (int)newheightT, size.Width / 2, size.Height);

      e.DrawImage(img.Image, rectT1, rectS1, GraphicsUnit.Pixel);
      e.DrawImage(img.Image, rectT2, rectS2, GraphicsUnit.Pixel);

      return e;
    }
    // move up/down left/right
    private Graphics RenderMethod18(Graphics e)
    {
      float iStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 1;
      }

      float newwidthT = frameCounter * iStep;
      if (newwidthT >= size.Width)
      {
        newwidthT = size.Width;
      }

      Rectangle rectS1 = new Rectangle(0, 0, img.Image.Width, img.Image.Height / 2);
      Rectangle rectS2 = new Rectangle(0, img.Image.Height / 2, img.Image.Width, img.Image.Height / 2);

      Rectangle rectT1 = new Rectangle((int)newwidthT - size.Width, 0, size.Width, size.Height / 2);
      Rectangle rectT2 = new Rectangle(size.Width - (int)newwidthT, size.Height / 2, size.Width, size.Height / 2);

      e.DrawImage(img.Image, rectT1, rectS1, GraphicsUnit.Pixel);
      e.DrawImage(img.Image, rectT2, rectS2, GraphicsUnit.Pixel);

      return e;
    }

    // open left/right up/down 4 stripes
    private Graphics RenderMethod19(Graphics e)
    {
      float sStep = (float)img.Image.Height / slideShowTransistionFrames;
      if (0 == sStep)
      {
        sStep = 1;
      }

      float tStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == tStep)
      {
        tStep = 1;
      }

      float newheightS = frameCounter * sStep;
      if (newheightS >= img.Image.Height)
      {
        newheightS = img.Image.Height;
      }
      float newheightT = frameCounter * tStep;
      if (newheightT >= size.Height)
      {
        newheightT = size.Height;
      }

      Rectangle rectS1 = new Rectangle(0, 0, img.Image.Width / 4, (int)newheightS);
      Rectangle rectS2 = new Rectangle(img.Image.Width / 4, img.Image.Height - (int)newheightS, img.Image.Width / 4, (int)newheightS);
      Rectangle rectS3 = new Rectangle(img.Image.Width / 4 * 2, 0, img.Image.Width / 4, (int)newheightS);
      Rectangle rectS4 = new Rectangle(img.Image.Width / 4 * 3, img.Image.Height - (int)newheightS, img.Image.Width / 4, (int)newheightS);

      Rectangle rectT1 = new Rectangle(0, 0, size.Width / 4, (int)newheightT);
      Rectangle rectT2 = new Rectangle(size.Width / 4, size.Height - (int)newheightT, size.Width / 4, (int)newheightT);
      Rectangle rectT3 = new Rectangle(size.Width / 4 * 2, 0, size.Width / 4, (int)newheightT);
      Rectangle rectT4 = new Rectangle(size.Width / 4 * 3, size.Height - (int)newheightT, size.Width / 4, (int)newheightT);

      e.DrawImage(img.Image, rectT1, rectS1, GraphicsUnit.Pixel);
      e.DrawImage(img.Image, rectT2, rectS2, GraphicsUnit.Pixel);
      e.DrawImage(img.Image, rectT3, rectS3, GraphicsUnit.Pixel);
      e.DrawImage(img.Image, rectT4, rectS4, GraphicsUnit.Pixel);

      return e;
    }

    // alpha blending
    private Graphics RenderMethod20(Graphics e)
    {
      float iStep = 1.0f / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 0.1f;
      }

      float alpha = frameCounter * iStep;
      if (alpha > 1.0f) alpha = 1.0f;


      float[][] ptsArray ={ new float[] {1, 0, 0, 0, 0},
                            new float[] {0, 1, 0, 0, 0},
                            new float[] {0, 0, 1, 0, 0},
                            new float[] {0, 0, 0, alpha, 0},
                            new float[] {0, 0, 0, 0, 1}};

      ColorMatrix colorMatrix = new ColorMatrix(ptsArray);

      // Create image attributes and set large gamma.
      ImageAttributes imageAttr = new ImageAttributes();
      imageAttr.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

      Rectangle dest = new Rectangle(new Point(0, 0), new Size(size.Width, size.Height));
      e.DrawImage(img.Image,
                  dest, 0, 0,
                  img.Image.Width, img.Image.Height,
                  GraphicsUnit.Pixel, imageAttr, null);

      return e;
    }
    // black & white blending
    private Graphics RenderMethod21(Graphics e)
    {
      float iStep = 1.0f / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 0.1f;
      }

      float alpha = frameCounter * iStep;
      if (alpha > 1.0f) alpha = 1.0f;

      float[][] ptsArray ={ new float[] {0.3f,0.3f,0.3f,0,0},
                              new float[] {0.59f,0.59f,0.59f,0,0},
                              new float[] {0.11f,0.11f,0.11f,0,0},
                              new float[] {0, 0, 0, alpha, 0},
                              new float[] {0, 0, 0, 0, 1}};

      ColorMatrix colorMatrix = new ColorMatrix(ptsArray);

      // Create image attributes and set large gamma.
      ImageAttributes imageAttr = new ImageAttributes();
      imageAttr.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

      Rectangle dest = new Rectangle(new Point(0, 0), new Size(size.Width, size.Height));
      e.DrawImage(img.Image,
                  dest, 0, 0,
                  img.Image.Width, img.Image.Height,
                  GraphicsUnit.Pixel, imageAttr, null);

      return e;
    }
    // sephia blending
    private Graphics RenderMethod22(Graphics e)
    {
      float iStep = 1.0f / slideShowTransistionFrames;
      if (0 == iStep)
      {
        iStep = 0.1f;
      }

      float alpha = frameCounter * iStep;
      if (alpha > 1.0f) alpha = 1.0f;

      float[][] ptsArray ={ new float[] {.393f, .349f, .272f, 0, 0},
                            new float[] {.769f, .686f, .534f, 0, 0},
                            new float[] {.189f, .168f, .131f, 0, 0},
                            new float[] {0, 0, 0, alpha, 0},
                            new float[] {0, 0, 0, 0, 1}};

      ColorMatrix colorMatrix = new ColorMatrix(ptsArray);

      // Create image attributes and set large gamma.
      ImageAttributes imageAttr = new ImageAttributes();
      imageAttr.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

      Rectangle dest = new Rectangle(new Point(0, 0), new Size(size.Width, size.Height));
      e.DrawImage(img.Image,
                  dest, 0, 0,
                  img.Image.Width, img.Image.Height,
                  GraphicsUnit.Pixel, imageAttr, null);

      return e;
    }
    // next picture
    private Graphics RenderMethod23(Graphics e)
    {
      e.DrawImage(img.Image, 0, 0, img.Image.Width, img.Image.Height);
      return e;
    }
    // 6 blocks
    private Graphics RenderMethod24(Graphics e)
    {
      Rectangle rectS1 = new Rectangle(0, 0, img.Image.Width / 3, img.Image.Height / 2);
      Rectangle rectS2 = new Rectangle(img.Image.Width / 3, 0, img.Image.Width / 3, img.Image.Height / 2);
      Rectangle rectS3 = new Rectangle(img.Image.Width / 3 * 2, 0, img.Image.Width / 3, img.Image.Height / 2);
      Rectangle rectS4 = new Rectangle(0, img.Image.Height / 2, img.Image.Width / 3, img.Image.Height / 2);
      Rectangle rectS5 = new Rectangle(img.Image.Width / 3, img.Image.Height / 2, img.Image.Width / 3, img.Image.Height / 2);
      Rectangle rectS6 = new Rectangle(img.Image.Width / 3 * 2, img.Image.Height / 2, img.Image.Width / 3, img.Image.Height / 2);

      Rectangle rectT1 = new Rectangle(0, 0, size.Width / 3, size.Height / 2);
      Rectangle rectT2 = new Rectangle(size.Width / 3, 0, size.Width / 3, size.Height / 2);
      Rectangle rectT3 = new Rectangle(size.Width / 3 * 2, 0, size.Width / 3, size.Height / 2);
      Rectangle rectT4 = new Rectangle(0, img.Image.Height / 2, size.Width / 3, size.Height / 2);
      Rectangle rectT5 = new Rectangle(size.Width / 3, img.Image.Height / 2, size.Width / 3, size.Height / 2);
      Rectangle rectT6 = new Rectangle(size.Width / 3 * 2, img.Image.Height / 2, size.Width / 3, size.Height / 2);

      e.DrawImage(img.Image, rectT1, rectS1, GraphicsUnit.Pixel);

      int mul = (int)slideShowTransistionFrames / 5;

      if (frameCounter > mul * 5)
        e.DrawImage(img.Image, rectT2, rectS2, GraphicsUnit.Pixel);
      if (frameCounter > mul * 2)
        e.DrawImage(img.Image, rectT3, rectS3, GraphicsUnit.Pixel);

      if (frameCounter > mul * 4)
        e.DrawImage(img.Image, rectT4, rectS4, GraphicsUnit.Pixel);
      if (frameCounter > mul)
        e.DrawImage(img.Image, rectT5, rectS5, GraphicsUnit.Pixel);
      if (frameCounter > mul * 3)
        e.DrawImage(img.Image, rectT6, rectS6, GraphicsUnit.Pixel);

      return e;
    }

    // open from top left
    private Graphics RenderMethod25(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iPosX = frameCounter * xStep;
      if (iPosX >= size.Width)
      {
        iPosX = size.Width;
      }
      float iPosY = frameCounter * yStep;
      if (iPosY >= size.Height)
      {
        iPosY = size.Height;
      }

      float iSizeX = frameCounter * xStep;
      if (iSizeX >= size.Width)
      {
        iSizeX = size.Width;
      }
      float iSizeY = frameCounter * yStep;
      if (iSizeY >= size.Height)
      {
        iSizeY = size.Height;
      }

      e.DrawImage(img.Image, new Rectangle(0, 0, (int)iPosX, (int)iPosY), 0, 0, (int)iSizeX, (int)iSizeY, GraphicsUnit.Pixel);
      return e;
    }
    // open from bottom left
    private Graphics RenderMethod26(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }


      float iPosX = frameCounter * xStep;
      if (iPosX >= size.Width)
      {
        iPosX = size.Width;
      }
      float iPosY = (float)size.Height - frameCounter * yStep;
      if (iPosY < 0)
      {
        iPosY = 0;
      }

      float iSizeX = frameCounter * xStep;
      if (iSizeX >= size.Width)
      {
        iSizeX = size.Width;
      }
      float iSizeY = frameCounter * yStep;
      if (iSizeY >= size.Height)
      {
        iSizeY = size.Height;
      }

      e.DrawImage(img.Image, new Rectangle(0, (int)iPosY, (int)iPosX, (int)iSizeY), 0, (int)iPosY, (int)iSizeX, (int)iSizeY, GraphicsUnit.Pixel);
      return e;
    }
    // open from top right
    private Graphics RenderMethod27(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iPosX = (float)size.Width - frameCounter * xStep;
      if (iPosX < 0)
      {
        iPosX = 0;
      }

      float iSizeX = frameCounter * xStep;
      if (iSizeX >= size.Width)
      {
        iSizeX = size.Width;
      }
      float iSizeY = frameCounter * yStep;
      if (iSizeY >= size.Height)
      {
        iSizeY = size.Height;
      }


      e.DrawImage(img.Image, new Rectangle((int)iPosX, 0, (int)iSizeX, (int)iSizeY), (int)iPosX, 0, (int)iSizeX, (int)iSizeY, GraphicsUnit.Pixel);
      return e;
    }
    // open from bottom right
    private Graphics RenderMethod28(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iPosX = (float)size.Width - frameCounter * xStep;
      if (iPosX < 0)
      {
        iPosX = 0;
      }
      float iPosY = (float)size.Height - frameCounter * yStep;
      if (iPosY < 0)
      {
        iPosY = 0;
      }

      float iSizeX = frameCounter * xStep;
      if (iSizeX >= size.Width)
      {
        iSizeX = size.Width;
      }
      float iSizeY = frameCounter * yStep;
      if (iSizeY >= size.Height)
      {
        iSizeY = size.Height;
      }

      e.DrawImage(img.Image, new Rectangle((int)iPosX, (int)iPosY, (int)iSizeX, (int)iSizeY), (int)iPosX, (int)iPosY, (int)iSizeX, (int)iSizeY, GraphicsUnit.Pixel);
      return e;
    }

    // open from left
    private Graphics RenderMethod29(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }

      float iSizeX = frameCounter * xStep;
      if (iSizeX >= size.Width)
      {
        iSizeX = size.Width;
      }

      e.DrawImage(img.Image, new Rectangle(0, 0, (int)iSizeX, size.Height), 0, 0, (int)iSizeX, size.Height, GraphicsUnit.Pixel);
      return e;
    }
    // open from right
    private Graphics RenderMethod30(Graphics e)
    {
      float xStep = (float)size.Width / slideShowTransistionFrames;
      if (0 == xStep)
      {
        xStep = 1;
      }

      float iSizeX = frameCounter * xStep;
      if (iSizeX >= size.Width)
      {
        iSizeX = size.Width;
      }

      e.DrawImage(img.Image, new Rectangle(size.Width - (int)iSizeX, 0, (int)iSizeX, size.Height), size.Width - (int)iSizeX, 0, (int)iSizeX, size.Height, GraphicsUnit.Pixel);
      return e;
    }
    // open from top
    private Graphics RenderMethod31(Graphics e)
    {
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iSizeY = frameCounter * yStep;
      if (iSizeY >= size.Height)
      {
        iSizeY = size.Height;
      }

      e.DrawImage(img.Image, new Rectangle(0, 0, size.Width, (int)iSizeY), 0, 0, size.Width, (int)iSizeY, GraphicsUnit.Pixel);
      return e;
    }
    // open from bottom
    private Graphics RenderMethod32(Graphics e)
    {
      float yStep = (float)size.Height / slideShowTransistionFrames;
      if (0 == yStep)
      {
        yStep = 1;
      }

      float iSizeY = frameCounter * yStep;
      if (iSizeY >= size.Height)
      {
        iSizeY = size.Height;
      }
      e.DrawImage(img.Image, new Rectangle(0, size.Height - (int)iSizeY, size.Width, (int)iSizeY), 0, size.Height - (int)iSizeY, size.Width, (int)iSizeY, GraphicsUnit.Pixel);
      return e;
    }

    // open from inside
    private Graphics RenderMethod33(Graphics e)
    {
      float iStepX = (float)size.Width / slideShowTransistionFrames;
      float iStepY = (float)size.Height / slideShowTransistionFrames;

      if (0 == iStepX)
      {
        iStepX = 1;
      }

      if (0 == iStepY)
      {
        iStepY = 1;
      }

      float newheight = frameCounter * iStepY;
      float newwidth = frameCounter * iStepX;

      if (newheight >= size.Height)
      {
        newheight = (float)size.Height;
      }

      if (newwidth >= size.Width)
      {
        newwidth = (float)size.Width;
      }

      e.DrawImage(img.Image, new Rectangle((size.Width - (int)newwidth) / 2, (size.Height - (int)newheight) / 2, (int)newwidth, (int)newheight),
                                           (size.Width - (int)newwidth) / 2, (size.Height - (int)newheight) / 2, (int)newwidth, (int)newheight,
                                           GraphicsUnit.Pixel);

      return e;
    }
    // 12 blocks
    private Graphics RenderMethod34(Graphics e)
    {
      int width14 = img.Image.Width / 4;
      int height13 = img.Image.Height / 3;

      Rectangle rectS1 = new Rectangle(0, 0, width14, height13);
      Rectangle rectS2 = new Rectangle(img.Image.Width / 4, 0, width14, height13);
      Rectangle rectS3 = new Rectangle(img.Image.Width / 4 * 2, 0, width14, height13);
      Rectangle rectS4 = new Rectangle(img.Image.Width / 4 * 3, 0, width14, height13);

      Rectangle rectS5 = new Rectangle(0, height13, width14, height13);
      Rectangle rectS6 = new Rectangle(img.Image.Width / 4, height13, width14, height13);
      Rectangle rectS7 = new Rectangle(img.Image.Width / 4 * 2, height13, width14, height13);
      Rectangle rectS8 = new Rectangle(img.Image.Width / 4 * 3, height13, width14, height13);

      Rectangle rectS9 = new Rectangle(0, height13 * 2, width14, height13);
      Rectangle rectS10 = new Rectangle(img.Image.Width / 4, height13 * 2, width14, height13);
      Rectangle rectS11 = new Rectangle(img.Image.Width / 4 * 2, height13 * 2, width14, height13);
      Rectangle rectS12 = new Rectangle(img.Image.Width / 4 * 3, height13 * 2, width14, height13);

      width14 = size.Width / 4;
      height13 = size.Height / 3;

      Rectangle rectT1 = new Rectangle(0, 0, width14, height13);
      Rectangle rectT2 = new Rectangle(width14, 0, width14, height13);
      Rectangle rectT3 = new Rectangle(width14 * 2, 0, width14, height13);
      Rectangle rectT4 = new Rectangle(width14 * 3, 0, width14, height13);

      Rectangle rectT5 = new Rectangle(0, height13, width14, height13);
      Rectangle rectT6 = new Rectangle(width14, height13, width14, height13);
      Rectangle rectT7 = new Rectangle(width14 * 2, height13, width14, height13);
      Rectangle rectT8 = new Rectangle(width14 * 3, height13, width14, height13);

      Rectangle rectT9 = new Rectangle(0, height13 * 2, width14, height13);
      Rectangle rectT10 = new Rectangle(width14, height13 * 2, width14, height13);
      Rectangle rectT11 = new Rectangle(width14 * 2, height13 * 2, width14, height13);
      Rectangle rectT12 = new Rectangle(width14 * 3, height13 * 2, width14, height13);


      e.DrawImage(img.Image, rectT1, rectS1, GraphicsUnit.Pixel);

      int mul = (int)slideShowTransistionFrames / 11;

      if (frameCounter > mul * 10)
        e.DrawImage(img.Image, rectT2, rectS2, GraphicsUnit.Pixel);
      if (frameCounter > mul * 7)
        e.DrawImage(img.Image, rectT3, rectS3, GraphicsUnit.Pixel);
      if (frameCounter > mul * 4)
        e.DrawImage(img.Image, rectT4, rectS4, GraphicsUnit.Pixel);

      if (frameCounter > mul * 5)
        e.DrawImage(img.Image, rectT5, rectS5, GraphicsUnit.Pixel);
      if (frameCounter > mul * 6)
        e.DrawImage(img.Image, rectT6, rectS6, GraphicsUnit.Pixel);
      if (frameCounter > mul * 2)
        e.DrawImage(img.Image, rectT7, rectS7, GraphicsUnit.Pixel);
      if (frameCounter > mul * 8)
        e.DrawImage(img.Image, rectT8, rectS8, GraphicsUnit.Pixel);

      if (frameCounter > mul * 3)
        e.DrawImage(img.Image, rectT9, rectS9, GraphicsUnit.Pixel);
      if (frameCounter > mul * 6)
        e.DrawImage(img.Image, rectT10, rectS10, GraphicsUnit.Pixel);
      if (frameCounter > mul * 9)
        e.DrawImage(img.Image, rectT11, rectS11, GraphicsUnit.Pixel);
      if (frameCounter > mul)
        e.DrawImage(img.Image, rectT12, rectS12, GraphicsUnit.Pixel);

      return e;
    }
    // picture frame
    private Graphics RenderMethod35(Graphics e)
    {
      e.DrawImage(img.Image,
                  img.Image.Width * 16 / 100, img.Image.Height * 20 / 100,
                  img.Image.Width * 68 / 100, img.Image.Height * 60 / 100);

      Image img1 = Image.FromStream(GetEmbeddedResourceStream("mKoenig.PictureSlide.photo_frame.png"));
      e.DrawImage(img1, 0, 0, size.Width, size.Height);

      return e;
    }
    // 24 blocks
    private Graphics RenderMethod36(Graphics e)
    {
      if (points36 == null)
      {
        #region generate new list
        points36 = new List<Rectangle>();
        for (int x = 0; x < 6; x++)
        {
          for (int y = 0; y < 4; y++)
          {
            points36.Add(new Rectangle(x * (size.Width / 6), y * (size.Height / 4), (size.Width / 6), (size.Height / 4)));
          }
        }
        #endregion
      }

      #region mix parts
      Random rand = new Random();
      for (int x = 0; x < 100; x++)
      {
        int a = rand.Next(points36.Count);
        int b = rand.Next(points36.Count);

        Rectangle tmp = points36[a];
        points36[a] = points36[b];
        points36[b] = tmp;
      }
      #endregion

      int cnt = 0;
      int mul = (int)slideShowTransistionFrames / 24;

      foreach (Rectangle p in points36)
      {
        e.DrawImage(img.Image, p, p, GraphicsUnit.Pixel);
        cnt += mul;

        if (cnt >= frameCounter) break;
      }
      return e;
    }

    #endregion

    public static Stream GetEmbeddedResourceStream(string ResourceName)
    {
      return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(ResourceName);
    }
  }
}
